using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Chat.Backend.Models;
using Chat.Backend.Data;
using Microsoft.Extensions.Logging;

namespace Chat.Backend.Services.Chat
{
    /// <summary>
    /// 聊天服务 - 处理消息的发送、接收和存储
    /// 转换自XmppChatImpl.java
    /// </summary>
    public class ChatService : IChatService
    {
        private readonly ILogger<ChatService> _logger;
        private readonly IXmppService _xmppService;
        private readonly IChatRepository _chatRepository;
        private readonly IUserService _userService;
        private readonly IEventBus _eventBus;
        private readonly IMediaService _mediaService;
        private readonly IEmojiService _emojiService;
        private readonly IVoiceService _voiceService;

        /// <summary>
        /// 构造函数
        /// </summary>
        public ChatService(
            ILogger<ChatService> logger,
            IXmppService xmppService,
            IChatRepository chatRepository,
            IUserService userService,
            IEventBus eventBus,
            IMediaService mediaService,
            IEmojiService emojiService,
            IVoiceService voiceService)
        {
            _logger = logger;
            _xmppService = xmppService;
            _chatRepository = chatRepository;
            _userService = userService;
            _eventBus = eventBus;
            _mediaService = mediaService;
            _emojiService = emojiService;
            _voiceService = voiceService;
            // 订阅XMPP消息接收事件
            _eventBus.Subscribe<XmppMessageReceivedEvent>(OnMessageReceived);
        }

        /// <summary>
        /// 发送文本消息
        /// </summary>
        public async Task<MessageResult> SendTextMessageAsync(string senderId, string receiverId, string content, bool isGroupChat = false)
        {
            try
            {
                // 验证发送者和接收者
                var sender = await _userService.GetUserByIdAsync(senderId);
                if (sender == null)
                {
                    throw new ApplicationException("发送者不存在");
                }
                
                // 创建消息对象
                var message = new ChatMessage
                {
                    Id = Guid.NewGuid().ToString(),
                    SenderId = senderId,
                    ReceiverId = receiverId,
                    Content = content,
                    Type = MessageType.Text,
                    IsGroupChat = isGroupChat,
                    SendTime = DateTime.UtcNow,
                    Status = MessageStatus.Sending
                };
                
                // 保存消息到数据库
                await _chatRepository.SaveMessageAsync(message);
                
                // 构建XMPP消息并发送
                var xmppTo = isGroupChat 
                    ? $"{receiverId}@conference.{_xmppService.Domain}" 
                    : $"{receiverId}@{_xmppService.Domain}";
                
                var messageType = isGroupChat ? MessageType.GroupChat : MessageType.Chat;
                
                // 构建消息体 (JSON格式)
                var messageBody = new ChatMessageBody
                {
                    MessageId = message.Id,
                    Type = "text",
                    Content = content,
                    Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
                };
                
                var messageJson = System.Text.Json.JsonSerializer.Serialize(messageBody);
                
                // 发送XMPP消息
                await _xmppService.SendMessageAsync(xmppTo, messageJson, messageType);
                
                // 更新消息状态
                message.Status = MessageStatus.Sent;
                await _chatRepository.UpdateMessageStatusAsync(message.Id, MessageStatus.Sent);
                
                // 返回结果
                return new MessageResult
                {
                    Success = true,
                    MessageId = message.Id
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"发送消息失败: 从 {senderId} 到 {receiverId}");
                
                // 如果消息已创建，更新状态为失败
                if (!string.IsNullOrEmpty(ex.Data["MessageId"]?.ToString()))
                {
                    var messageId = ex.Data["MessageId"].ToString();
                    await _chatRepository.UpdateMessageStatusAsync(messageId, MessageStatus.Failed);
                }
                
                return new MessageResult
                {
                    Success = false,
                    Error = ex.Message
                };
            }
        }

        /// <summary>
        /// 发送图片消息
        /// </summary>
        public async Task<MessageResult> SendImageMessageAsync(string senderId, string receiverId, byte[] imageData, bool isGroupChat = false)
        {
            try
            {
                // 上传图片到媒体服务
                var imageUrl = await _mediaService.UploadImageAsync(imageData, senderId);
                
                // 创建消息对象
                var message = new ChatMessage
                {
                    Id = Guid.NewGuid().ToString(),
                    SenderId = senderId,
                    ReceiverId = receiverId,
                    Content = imageUrl,
                    Type = MessageType.Image,
                    IsGroupChat = isGroupChat,
                    SendTime = DateTime.UtcNow,
                    Status = MessageStatus.Sending
                };
                
                // 保存消息到数据库
                await _chatRepository.SaveMessageAsync(message);
                
                // 构建消息体
                var messageBody = new ChatMessageBody
                {
                    MessageId = message.Id,
                    Type = "image",
                    Content = imageUrl,
                    Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
                };
                
                var messageJson = System.Text.Json.JsonSerializer.Serialize(messageBody);
                
                // 发送XMPP消息
                var xmppTo = isGroupChat 
                    ? $"{receiverId}@conference.{_xmppService.Domain}" 
                    : $"{receiverId}@{_xmppService.Domain}";
                
                var messageType = isGroupChat ? MessageType.GroupChat : MessageType.Chat;
                
                await _xmppService.SendMessageAsync(xmppTo, messageJson, messageType);
                
                // 更新消息状态
                message.Status = MessageStatus.Sent;
                await _chatRepository.UpdateMessageStatusAsync(message.Id, MessageStatus.Sent);
                
                return new MessageResult
                {
                    Success = true,
                    MessageId = message.Id
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"发送图片消息失败: 从 {senderId} 到 {receiverId}");
                
                // 如果消息已创建，更新状态为失败
                if (!string.IsNullOrEmpty(ex.Data["MessageId"]?.ToString()))
                {
                    var messageId = ex.Data["MessageId"].ToString();
                    await _chatRepository.UpdateMessageStatusAsync(messageId, MessageStatus.Failed);
                }
                
                return new MessageResult
                {
                    Success = false,
                    Error = ex.Message
                };
            }
        }
        /// <summary>
        /// 发送表情包消息
        /// </summary>
        public async Task<MessageResult> SendEmojiMessageAsync(string senderId, string receiverId, string emojiId, bool isGroupChat = false)
        {
            // 直接调用表情包服务
            return await _emojiService.SendEmojiMessageAsync(senderId, receiverId, emojiId, isGroupChat);
        }

        /// <summary>
        /// 发送语音消息（优化版）
        /// </summary>
        public async Task<MessageResult> SendVoiceMessageAsync(string senderId, string receiverId, byte[] audioData, AudioFormat format, bool isGroupChat = false)
        {
            try
            {
                // 处理语音数据
                var processResult = await _voiceService.ProcessVoiceMessageAsync(audioData, senderId, format);
                
                if (!processResult.Success)
                {
                    return new MessageResult
                    {
                        Success = false,
                        Error = processResult.Error
                    };
                }
                
                // 创建消息对象
                var message = new ChatMessage
                {
                    Id = Guid.NewGuid().ToString(),
                    SenderId = senderId,
                    ReceiverId = receiverId,
                    Content = processResult.Url,
                    Type = MessageType.Voice,
                    IsGroupChat = isGroupChat,
                    SendTime = DateTime.UtcNow,
                    Status = MessageStatus.Sending,
                    Duration = processResult.Duration
                };
                
                // 保存消息到数据库
                await _chatRepository.SaveMessageAsync(message);
                
                // 构建消息体，添加格式信息
                var messageBody = new ChatMessageBody
                {
                    MessageId = message.Id,
                    Type = "voice",
                    Content = processResult.Url,
                    Duration = processResult.Duration,
                    Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
                };
                
                // 添加格式信息
                var attributes = new Dictionary<string, string>
                {
                    { "format", processResult.Format }
                };
                messageBody.Attributes = attributes;
                
                var messageJson = System.Text.Json.JsonSerializer.Serialize(messageBody);
                
                // 发送XMPP消息
                var xmppTo = isGroupChat 
                    ? $"{receiverId}@conference.{_xmppService.Domain}" 
                    : $"{receiverId}@{_xmppService.Domain}";
                
                var messageType = isGroupChat ? MessageType.GroupChat : MessageType.Chat;
                
                await _xmppService.SendMessageAsync(xmppTo, messageJson, messageType);
                
                // 更新消息状态
                message.Status = MessageStatus.Sent;
                await _chatRepository.UpdateMessageStatusAsync(message.Id, MessageStatus.Sent);
                
                return new MessageResult
                {
                    Success = true,
                    MessageId = message.Id
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"发送语音消息失败: 从 {senderId} 到 {receiverId}");
                
                return new MessageResult
                {
                    Success = false,
                    Error = ex.Message
                };
            }
        }

        /// <summary>
        /// 发送位置消息
        /// </summary>
        public async Task<MessageResult> SendLocationMessageAsync(string senderId, string receiverId, double latitude, double longitude, string address, bool isGroupChat = false)
        {
            try
            {
                // 创建位置信息对象
                var locationInfo = new LocationInfo
                {
                    Latitude = latitude,
                    Longitude = longitude,
                    Address = address
                };
                
                // 将位置信息序列化为JSON字符串
                var locationJson = System.Text.Json.JsonSerializer.Serialize(locationInfo);
                
                // 创建消息对象
                var message = new ChatMessage
                {
                    Id = Guid.NewGuid().ToString(),
                    SenderId = senderId,
                    ReceiverId = receiverId,
                    Content = locationJson,
                    Type = MessageType.Location,
                    IsGroupChat = isGroupChat,
                    SendTime = DateTime.UtcNow,
                    Status = MessageStatus.Sending
                };
                
                // 保存消息到数据库
                await _chatRepository.SaveMessageAsync(message);
                
                // 构建消息体
                var messageBody = new ChatMessageBody
                {
                    MessageId = message.Id,
                    Type = "location",
                    Content = locationJson,
                    Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
                };
                
                var messageJson = System.Text.Json.JsonSerializer.Serialize(messageBody);
                
                // 发送XMPP消息
                var xmppTo = isGroupChat 
                    ? $"{receiverId}@conference.{_xmppService.Domain}" 
                    : $"{receiverId}@{_xmppService.Domain}";
                
                var messageType = isGroupChat ? MessageType.GroupChat : MessageType.Chat;
                
                await _xmppService.SendMessageAsync(xmppTo, messageJson, messageType);
                
                // 更新消息状态
                message.Status = MessageStatus.Sent;
                await _chatRepository.UpdateMessageStatusAsync(message.Id, MessageStatus.Sent);
                
                return new MessageResult
                {
                    Success = true,
                    MessageId = message.Id
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"发送位置消息失败: 从 {senderId} 到 {receiverId}");
                
                // 如果消息已创建，更新状态为失败
                if (!string.IsNullOrEmpty(ex.Data["MessageId"]?.ToString()))
                {
                    var messageId = ex.Data["MessageId"].ToString();
                    await _chatRepository.UpdateMessageStatusAsync(messageId, MessageStatus.Failed);
                }
                
                return new MessageResult
                {
                    Success = false,
                    Error = ex.Message
                };
            }
        }

        /// <summary>
        /// 获取聊天历史记录
        /// </summary>
        public async Task<IEnumerable<ChatMessage>> GetChatHistoryAsync(string userId, string contactId, bool isGroupChat, int skip, int take)
        {
            try
            {
                return await _chatRepository.GetChatHistoryAsync(userId, contactId, isGroupChat, skip, take);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取聊天历史记录失败: 用户 {userId} 和联系人 {contactId}");
                throw;
            }
        }

        /// <summary>
        /// 创建群聊
        /// </summary>
        public async Task<GroupChatResult> CreateGroupChatAsync(string creatorId, string groupName, List<string> memberIds)
        {
            try
            {
                // 创建群聊对象
                var groupChat = new GroupChat
                {
                    Id = Guid.NewGuid().ToString(),
                    Name = groupName,
                    CreatorId = creatorId,
                    CreateTime = DateTime.UtcNow,
                    Members = new List<GroupChatMember>()
                };
                
                // 添加创建者作为群主
                groupChat.Members.Add(new GroupChatMember
                {
                    UserId = creatorId,
                    Role = GroupChatRole.Owner,
                    JoinTime = DateTime.UtcNow
                });
                
                // 添加其他成员
                foreach (var memberId in memberIds)
                {
                    if (memberId != creatorId)
                    {
                        groupChat.Members.Add(new GroupChatMember
                        {
                            UserId = memberId,
                            Role = GroupChatRole.Member,
                            JoinTime = DateTime.UtcNow
                        });
                    }
                }
                
                // 保存群聊到数据库
                await _chatRepository.CreateGroupChatAsync(groupChat);
                
                // 创建XMPP MUC (Multi-User Chat)
                var roomJid = $"{groupChat.Id}@conference.{_xmppService.Domain}";
                await _xmppService.JoinGroupAsync(roomJid, creatorId);
                
                // 发送群创建通知消息
                var systemMessage = new ChatMessage
                {
                    Id = Guid.NewGuid().ToString(),
                    SenderId = "system",
                    ReceiverId = groupChat.Id,
                    Content = $"群聊 \"{groupName}\" 已创建",
                    Type = MessageType.System,
                    IsGroupChat = true,
                    SendTime = DateTime.UtcNow,
                    Status = MessageStatus.Sent
                };
                
                await _chatRepository.SaveMessageAsync(systemMessage);
                
                return new GroupChatResult
                {
                    Success = true,
                    GroupId = groupChat.Id
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"创建群聊失败: 创建者 {creatorId}");
                return new GroupChatResult
                {
                    Success = false,
                    Error = ex.Message
                };
            }
        }

        /// <summary>
        /// 处理接收到的XMPP消息
        /// </summary>
        private async Task OnMessageReceived(XmppMessageReceivedEvent evt)
        {
            try
            {
                // 解析消息体
                var messageBody = System.Text.Json.JsonSerializer.Deserialize<ChatMessageBody>(evt.Body);
                
                // 解析发送者JID
                var senderJid = evt.From;
                var senderId = senderJid.Split('@')[0];
                
                // 解析接收者JID
                var receiverJid = evt.To;
                var receiverId = receiverJid.Split('@')[0];
                
                // 确定是否为群聊消息
                var isGroupChat = evt.Type.Equals("groupchat", StringComparison.OrdinalIgnoreCase);
                
                // 创建消息对象
                var message = new ChatMessage
                {
                    Id = messageBody.MessageId,
                    SenderId = senderId,
                    ReceiverId = receiverId,
                    Content = messageBody.Content,
                    Type = GetMessageType(messageBody.Type),
                    IsGroupChat = isGroupChat,
                    SendTime = DateTimeOffset.FromUnixTimeMilliseconds(messageBody.Timestamp).UtcDateTime,
                    ReceiveTime = DateTime.UtcNow,
                    Status = MessageStatus.Received,
                    Duration = messageBody.Duration
                };
                
                // 保存消息到数据库
                await _chatRepository.SaveMessageAsync(message);
                
                // 发送消息回执
                if (!isGroupChat && !string.IsNullOrEmpty(messageBody.MessageId))
                {
                    await SendMessageReceiptAsync(receiverId, senderId, messageBody.MessageId);
                }
                
                // 通知应用层有新消息
                await _eventBus.PublishAsync(new MessageReceivedEvent
                {
                    Message = message
                });
                
                // 发送推送通知
                if (!isGroupChat)
                {
                    var sender = await _userService.GetUserByIdAsync(senderId);
                    var pushMessage = $"{sender.Nickname}: {GetMessageContentPreview(message)}";
                    
                    await _eventBus.PublishAsync(new PushNotificationEvent
                    {
                        UserId = receiverId,
                        Title = sender.Nickname,
                        Body = GetMessageContentPreview(message),
                        Data = new Dictionary<string, string>
                        {
                            { "type", "chat_message" },
                            { "senderId", senderId },
                            { "messageId", message.Id }
                        }
                    });
                }
                else
                {
                    var group = await _chatRepository.GetGroupChatByIdAsync(message.ReceiverId);
                    var sender = await _userService.GetUserByIdAsync(senderId);
                    
                    foreach (var member in group.Members)
                    {
                        if (member.UserId != senderId) // 不给发送者发送推送
                        {
                            await _eventBus.PublishAsync(new PushNotificationEvent
                            {
                                UserId = member.UserId,
                                Title = $"{sender.Nickname} @ {group.Name}",
                                Body = GetMessageContentPreview(message),
                                Data = new Dictionary<string, string>
                                {
                                    { "type", "group_message" },
                                    { "groupId", group.Id },
                                    { "senderId", senderId },
                                    { "messageId", message.Id }
                                }
                            });
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "处理接收消息失败");
            }
        }

        /// <summary>
        /// 发送消息回执
        /// </summary>
        private async Task SendMessageReceiptAsync(string senderId, string receiverId, string messageId)
        {
            try
            {
                // 构建回执消息体
                var receiptBody = new ChatMessageReceiptBody
                {
                    MessageId = messageId,
                    Status = "received",
                    Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
                };
                
                var receiptJson = System.Text.Json.JsonSerializer.Serialize(receiptBody);
                
                // 发送XMPP回执消息
                var xmppTo = $"{receiverId}@{_xmppService.Domain}";
                await _xmppService.SendMessageAsync(xmppTo, receiptJson, MessageType.Chat);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"发送消息回执失败: 消息ID {messageId}");
            }
        }

        /// <summary>
        /// 获取消息内容预览
        /// </summary>
        private string GetMessageContentPreview(ChatMessage message)
        {
            switch (message.Type)
            {
                case MessageType.Text:
                    // 截取文本前30个字符作为预览
                    return message.Content.Length <= 30 
                        ? message.Content 
                        : $"{message.Content.Substring(0, 27)}...";
                
                case MessageType.Image:
                    return "[图片]";
                
                case MessageType.Voice:
                    return "[语音]";
                
                case MessageType.Video:
                    return "[视频]";
                
                case MessageType.Location:
                    return "[位置]";
                
                case MessageType.File:
                    return "[文件]";
                
                default:
                    return "[消息]";
            }
        }

        /// <summary>
        /// 根据消息类型字符串获取枚举值
        /// </summary>
        private MessageType GetMessageType(string type)
        {
            switch (type.ToLower())
            {
                case "text":
                    return MessageType.Text;
                
                case "image":
                    return MessageType.Image;
                
                case "voice":
                    return MessageType.Voice;
                
                case "video":
                    return MessageType.Video;
                
                case "location":
                    return MessageType.Location;
                
                case "file":
                    return MessageType.File;
                
                case "system":
                    return MessageType.System;
                
                default:
                    return MessageType.Unknown;
            }
        }
    }

    /// <summary>
    /// 聊天消息接口
    /// </summary>
    public interface IChatService
    {
        Task<MessageResult> SendTextMessageAsync(string senderId, string receiverId, string content, bool isGroupChat = false);
        Task<MessageResult> SendImageMessageAsync(string senderId, string receiverId, byte[] imageData, bool isGroupChat = false);
        Task<MessageResult> SendVoiceMessageAsync(string senderId, string receiverId, byte[] audioData, int duration, bool isGroupChat = false);
        Task<MessageResult> SendLocationMessageAsync(string senderId, string receiverId, double latitude, double longitude, string address, bool isGroupChat = false);
        Task<IEnumerable<ChatMessage>> GetChatHistoryAsync(string userId, string contactId, bool isGroupChat, int skip, int take);
        Task<GroupChatResult> CreateGroupChatAsync(string creatorId, string groupName, List<string> memberIds);
    }
}